home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / et / et3_0-a1.lha / et3 / src / Application.C < prev    next >
C/C++ Source or Header  |  1992-08-10  |  10KB  |  457 lines

  1. #ifdef __GNUG__
  2. #pragma implementation
  3. #endif
  4.  
  5. #include "Application.h"
  6.  
  7. #include "Document.h"
  8. #include "Class.h"
  9. #include "Storage.h"
  10. #include "FileDialog.h"
  11. #include "ObjectTable.h"
  12. #include "ClassManager.h"
  13. #include "ClipBoard.h"
  14. #include "ProgEnv.h"
  15. #include "Buttons.h"
  16. #include "StreamConnection.h"
  17. #include "WindowSystem.h"
  18. #include "Env.h"
  19. #include "ProgressDialog.h"
  20. #include "Data.h"
  21. #include "Alert_e.h"
  22. #include "Error.h"
  23. #include "Menu.h"
  24. #include "String.h"
  25. #include "Expander.h"
  26. #include "MenuBar.h"
  27. #include "DebuggerIF.h"
  28.  
  29. StreamConnection    *gRpc;
  30. Application         *gApplication;
  31. ClipBoard           *gClipBoard;
  32. int                 gArgc;
  33. char                **gArgv;
  34.  
  35. extern char *gProgPath;
  36.  
  37. //---- AppRpcConnection --------------------------------------------------------
  38.  
  39. class AppRpcConnection : public StreamConnection {
  40. public:
  41.     MetaDef(AppRpcConnection);
  42.     AppRpcConnection() : StreamConnection(-1)
  43.     { Open(gSystem->OpenConnection(SERVERNAME, SERVICENAME));
  44.       Talk(0, "enroll", gProgname); }
  45.     ~AppRpcConnection()
  46.     { SendTo(0, "remove", gProgname); }
  47.     void Dispatch(int from, char *req, char *buf, int len, char *&ret, int &retlen)
  48.     { gApplication->ExtCommand(from, req, buf, len, ret, retlen);
  49.       gWindowSystem->Update(); }
  50. };
  51.  
  52. NewMetaImpl0(AppRpcConnection,StreamConnection);
  53.  
  54. //---- ApplIntHandler ----------------------------------------------------------
  55.  
  56. class ApplIntHandler : public SysEvtHandler {
  57. public:
  58.     MetaDef(ApplIntHandler);
  59.     ApplIntHandler() : SysEvtHandler(eSigInterrupt)
  60.     { }
  61.     void Notify(SysEventCodes, int)
  62.     { if (gApplication) gApplication->Inspect(); }
  63. };
  64.  
  65. NewMetaImpl0(ApplIntHandler,SysEvtHandler);
  66.  
  67. //---- ApplErrorHandler --------------------------------------------------------
  68.  
  69. static void ApplErrorHandler(int level, bool, char *location, char *msg)
  70. {
  71.     gApplication->DoOnError(level, location, msg);
  72.  
  73. //---- Application -------------------------------------------------------------
  74.  
  75. NewAbstractMetaImpl(Application,Manager, (T(lastWindowPos), TS(version),
  76.     T(mainDocumentType), TP(fileDialog), TP(gApplication), TP(gClipBoard),
  77.     TVP(gArgv,gArgc), TP(gClassManager)));
  78.  
  79. FileDialog *Application::fileDialog;
  80.  
  81. Application::Application(int ac, char **av, Symbol &dt)
  82. {
  83.     if (gApplication)
  84.     Error("Application", "only one Application !!");
  85.  
  86.     gApplication= this;
  87.     version= "Version 3.0, 7/1/92, \251IFI & UBS-UBILAB";
  88.     gArgc= ac;
  89.     gArgv= av;
  90.     mainDocumentType= dt;
  91.  
  92.     ETInit(gArgv);
  93.     SetName(ProgramName());
  94.     WindowSystem::WSInit();
  95.     
  96.     SetErrorHandler(ApplErrorHandler);
  97.     lastWindowPos= Point(150, 100);
  98.     char *cp= Env::GetValue("Document.Position", (char*)0);
  99.     if (cp) {
  100.     IStream is(strlen(cp), cp);
  101.     is >> lastWindowPos;
  102.     }
  103. }
  104.  
  105. Application::~Application()
  106. {
  107.     if (gApplication == this)
  108.     gApplication= 0;
  109.  
  110.     SafeDelete(fileDialog);
  111. }
  112.  
  113. char *Application::GetName()
  114. {
  115.     return gProgname;
  116. }
  117.  
  118. FileDialog *Application::MakeFileDialog()
  119. {
  120.     return new FileDialog;
  121. }
  122.  
  123. void Application::NewManager(Symbol type)
  124. {
  125.     Manager *mp= DoMakeManager(type); // let user make his managers
  126.     if (mp) {
  127.     AddManager(mp);
  128.     mp->Show();
  129.     }
  130. }
  131.  
  132. void Application::ParseCommandLine(int argc, char **argv)
  133. {
  134.     for (int i= 1; i < argc;) {
  135.     if (argv[i][0] == '-') {
  136.         int n= DoParseOptions(argv[i], argv[i+1]);
  137.         if (n > 0)
  138.         i+= n;
  139.         else
  140.         i++;
  141.     } else 
  142.         OpenDocument(argv[i++]);
  143.     }
  144. }
  145.  
  146. int Application::DoParseOptions(char *arg0, char*)
  147. {
  148.     if (arg0[0] == '-' && arg0[1] == 'E') {
  149.     if (arg0[2] == 'e') 
  150.         gProgEnv->Start();
  151.     if (arg0[2] == 'h') 
  152.         gProgEnv->ShowInHierarchy(this->IsA());
  153.     return 1;
  154.     }
  155.     return 0;
  156. }
  157.  
  158. void Application::RemoveManager(Manager *mp)
  159. {
  160.     Manager::RemoveManager(mp);
  161.     if (Size() <= 0 && !IsOpen())
  162.     Quit();
  163. }
  164.  
  165. char *Application::ProgramName()
  166. {
  167.     return BaseName(gProgname);
  168. }
  169.  
  170. Point Application::GetInitialWindowPos()
  171. {
  172.     return GetNewDocumentPos();
  173. }
  174.  
  175. void Application::About()
  176. {
  177.     ShowAlert(eAlertSun, "%s %s", ProgramName(), version);
  178. }
  179.  
  180. Command *Application::DoMenuCommand(int cmd)
  181. {
  182.     switch(cmd) {
  183.     case cNEW:
  184.     NewManager(mainDocumentType);
  185.     break;
  186.     case cQUIT:
  187.     Quit();
  188.     break;
  189.     case cABOUT:
  190.     About();
  191.     break;
  192.     case cOPEN:
  193.     OpenDocument(0);
  194.     break;
  195.     default:
  196.     Manager::DoMenuCommand(cmd);
  197.     break;
  198.     }
  199.     return gNoChanges;
  200. }
  201.  
  202. void Application::DoSetupMenu(Menu *m)
  203. {
  204.     Manager::DoSetupMenu(m);
  205.     m->EnableItems(cOPEN, cNEW, cQUIT, cABOUT, 0);
  206. }
  207.  
  208. void Application::Control(int id, int part, void *val)
  209. {
  210.     SendDown(id, part, val);
  211. }
  212.  
  213. void Application::ExtCommand(int from, char *rq, char *args, int len,
  214.                             char *&ret, int &retlen)
  215. {
  216.     char req[100];
  217.     strcpy(req, rq);
  218.     
  219.     if (strcmp(req, "remove") == 0) {
  220.     gWindowSystem->ExtCommand(from, req, args, len, ret, retlen);
  221.     return;
  222.     }
  223.     
  224.     char *cp= strchr(req, ':');
  225.     if (cp) {
  226.     *cp++= 0;
  227.     if (strcmp(req, "clipboard") == 0)
  228.         gWindowSystem->ExtCommand(from, cp, args, len, ret, retlen);
  229.     
  230.     else if (strcmp(req, "document") == 0) {
  231.         Iter next(MakeIterator());
  232.         Manager *first= (Manager*)next();
  233.         if (first)
  234.         first->ExtCommand(from, cp, args, len, ret, retlen);
  235.     } else if (strcmp(req, "application") == 0) {
  236.         if (strcmp(cp, "quit") == 0)
  237.         Quit();
  238.         else if (strcmp(cp, "about") == 0)
  239.         About();
  240.         else if (strcmp(cp, "new") == 0)
  241.         NewManager(mainDocumentType);
  242.         else if (strcmp(cp, "open") == 0)
  243.         OpenDocument(args);
  244.         else if (strcmp(cp, "inspect") == 0)
  245.         Inspect();
  246.         ret= "ok";
  247.     }
  248.     }
  249. }
  250.  
  251. void Application::Quit()
  252. {
  253.     if (Close())
  254.     gSystem->ExitControl();
  255. }
  256.  
  257. Manager *Application::DoMakeManager(Symbol type)
  258. {
  259.     return DoMakeDocuments(type);
  260. }
  261.  
  262. bool Application::OpenDocument(char *name)
  263. {
  264.     bool rc= FALSE, dodelete= FALSE;
  265.     Data *data;
  266.     Manager *mp;
  267.  
  268.     if (name == 0) {
  269.     if (fileDialog == 0)
  270.         fileDialog= MakeFileDialog();
  271.     if (fileDialog->ShowInWindow(eFDRead, 0, this) != cIdOk)
  272.         return FALSE;
  273.     name= fileDialog->FileName();
  274.     data= fileDialog->GetData();
  275.     } else {
  276.     data= new FileData(name);
  277.     dodelete= TRUE;
  278.     }
  279.       
  280.     if (!CanOpen(data)) {
  281.     ShowAlert(eAlertNote, "cannot handle document @I%s@P (%s)\n",
  282.                     data->FullName(), data->Type().AsString());
  283.     } else {
  284.     mp= DoMakeManager(data->Type()); // let user make his managers
  285.     if (mp) {
  286.         AddManager(mp);
  287.         mp->Show();
  288.         ((Document*)mp)->LoadData(data, TRUE);
  289.         gWindowSystem->Update();
  290.         rc= TRUE;
  291.     }
  292.     }
  293.     if (dodelete)
  294.     delete data;
  295.     return rc;
  296. }
  297.  
  298. bool Application::CanOpen(Data *data)
  299. {
  300.     if (mainDocumentType == cDocTypeUndef || mainDocumentType == data->Type())
  301.     return TRUE;
  302.     if (mainDocumentType == cDocTypeAscii && data->IsAscii())
  303.     return TRUE;
  304.     return FALSE;
  305. }
  306.  
  307. void Application::MakeInitManager()
  308. {
  309.     if (Size() <= 0)
  310.     NewManager(mainDocumentType);
  311. }
  312.  
  313. int Application::Run()
  314. {
  315.     gRpc= new AppRpcConnection;
  316.     gClipBoard= new ClipBoard;
  317.     gProgress= new ProgressImpl;
  318.     gSystem->AddSignalHandler(new ApplIntHandler);
  319.     
  320.     ParseCommandLine(gArgc, gArgv);
  321.  
  322.     MakeInitManager();
  323.  
  324.     Open();
  325.  
  326.     gSystem->Control();
  327.     
  328.     SetErrorHandler(DefaultErrorHandler);
  329.  
  330.     SafeDelete(gClipBoard);
  331.     SafeDelete(gRpc);
  332.     SafeDelete(gProgress);
  333.     
  334.     return 0;
  335. }
  336.  
  337. void Application::DoOnError(int level, char *location, char *msg)
  338. {
  339.     static bool inError= FALSE;
  340.     
  341.     if (level < Env::GetValue("System.IgnoreLevel", cError) || inError)
  342.     return;
  343.     inError= TRUE;
  344.     
  345.     char *type= "Warning";
  346.     if (level >= cFatal)
  347.     type= "Fatal";
  348.     else if (level >= cSysError)
  349.     type= "SysError";
  350.     else if (level >= cError)
  351.     type= "Error";
  352.     
  353.     cerr.form("%s: %s in <%s>: %s\n", ProgramName(), type, location, msg);
  354.     if (level >= cError) {
  355.     int r= ShowAlert(eAlertError, "%s: %s\nin @B%s@B: %s", ProgramName(),
  356.                             type, location, msg);
  357.     switch (r) {
  358.     case cIdIgnore:
  359.         break;
  360.         
  361.     case cIdAbort:
  362.         gSystem->Abort();
  363.         
  364.     case cIdInspect:
  365.         DebuggerIF *dbg= new DebuggerIF;
  366.         dbg->Attach(gProgPath, gSystem->GetPid());
  367.         delete dbg;
  368.         //gSystem->Wait(15000);
  369.         //ShowAlert(eAlertError, "%s: Could not attach to debugger\n", ProgramName());
  370.         //Inspect();
  371.         break;
  372.     }
  373.     }
  374.     inError= FALSE;
  375. }
  376.  
  377. //---- obsolete ----------------------------------------------------------------
  378.  
  379. Document *Application::FindDocument(int id)
  380. {
  381.     return (Document*) Application::FindManager(id);
  382. }
  383.  
  384. Document *Application::DoMakeDocuments(Symbol)
  385. {
  386.     return 0;
  387. }
  388.  
  389. bool Application::CloseAllDocuments()
  390. {
  391.     return Close();
  392. }
  393.  
  394. void Application::AddDocument(Document *dp)
  395. {
  396.     AddManager(dp);
  397. }
  398.  
  399. void Application::RemoveDocument(Document *mp)
  400. {
  401.     RemoveManager(mp);
  402. }
  403.  
  404. void Application::NewDocument(Symbol)
  405. {
  406. }
  407.  
  408. Point Application::GetNewDocumentPos()
  409. {
  410.     Point p= lastWindowPos;
  411.     lastWindowPos+= Point(40, 30);
  412.     return p;
  413. }
  414.  
  415. //---- external calls of ET++PE ------------------------------------------------
  416.  
  417. extern "C" int ETPE_Enter(Object *op);
  418.  
  419. static int CallCount= 0;
  420.  
  421. int ETPE_Enter(Object *op)
  422. {
  423.     int level= CallCount++;
  424.     Port *p= GrGetPort();
  425.  
  426.     if (op == 0)
  427.     op= gApplication;
  428.     
  429.     if (!ObjectTable::PtrIsValid(op)) {
  430.     fprintf(stderr, "ET++PE: 0x%x is not an instance of Object\n", (int)op);
  431.     return 0;
  432.     }
  433.  
  434.     op->Inspect();
  435.  
  436.     //---- nested event-loop    
  437.     while (CallCount > level && !gQuitApp)
  438.     gSystem->InnerLoop();
  439.     
  440.     if (gQuitApp)
  441.     CallCount= 0;
  442.     
  443.     fprintf(stderr, "\nETPE: Exit\n");
  444.     
  445.     GrSetPort(p);
  446.     
  447.     return level;
  448. }
  449.  
  450. int gCallCount(int d)
  451. {
  452.     CallCount+= d;
  453.     return CallCount;
  454. }
  455.  
  456.